<!DOCTYPE html>
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
	<title>SoundJS: Test Suite</title>

	<link type="text/css" href="../_assets/css/jquery-ui-1.8.18.custom.css"
		  rel="stylesheet"/>
	<!-- update to http://code.jquery.com/ui/1.9.2/themes/base/jquery-ui.css? -->
	<style type="text/css">
		/* define a width for the sliders by styling the wrapping div */
		.panSlider,
		.volumeSlider,
		.posSlider,
		.offsetSlider,
		.delaySlider,
		.startTimeSlider,
		.durationSlider,
		.masterVolumeSlider,
		.loopSlider,
		.instanceLoopSlider,
		.instanceStartTimeSlider,
		.instanceDurationSlider
		{
			width: 200px;
		}
	</style>

	<link href="../_assets/css/shared.css" rel="stylesheet" type="text/css"/>
	<link href="../_assets/css/examples.css" rel="stylesheet" type="text/css"/>
	<link href="../_assets/css/soundjs.css" rel="stylesheet" type="text/css"/>
	<script src="../_assets/js/examples.js"></script>
	<style>
		FORM {
			text-align: left;
			width: 450px;
			padding: 5px;
			float: left;
		}

		FORM P {
			margin: 0 0 10px 0;
		}

		td {
			min-width: 95px;
		}

		#instanceControls {
		}

		.select {
			width: 100%;
			height: 80px;
		}

		.disabled {
			color: #333;
			font-style: italic;
		}

		.disabled p, .disabled .nodisable {
			color: #333;
			font-style: normal;
		}

		.plugin {
			font-size: 16px;
			font-weight: bold;
		}
	</style>
</head>

<body onload="init()">

<header class="SoundJS">
	<h1>Test Suite</h1>

	<p>This test suite loads and plays a number of sounds, defined in the
		source. Playing sounds can be controlled, stopped, etc</p>
</header>

<div class="content" id="content" style="height: auto">
	<div>
		<a href="?type=normal">Web Audio with HTML Audio then Flash
			Fallbacks</a> | <a href="?type=html5">HTML Audio Only</a> | <a
			href="?type=flash">Flash Only</a>
	</div>

	<div class="plugin">
		<p id="activePlugin">Active Plugin is</p>
	</div>

	<form id="playControls">
		<p>Select a sound to play it. <br/>Each sound shows how many instances
			it can play at once.</p>
		<select id="library" multiple="multiple" class="select"></select><br/>

		<input type="button" id="playSoundBtn" value="Play"/>
		<input type="button" id="createSoundBtn" value="Create"/>

		<label for="interrupt">Interrupt</label>
		<select id="interrupt">
			<option selected="selected" value="any">
				Any
			</option>
			<option value="none">None</option>
			<option value="early">Early</option>
			<option value="late">Late</option>
		</select>
		<input id="stopAllSoundsBtn" name="stopAll" type="button"
			   value="Stop All"/>
		<input id="muteAllSoundsBtn" name="muteAll" type="button"
			   value="Mute All"/>

		<br/>
		<br/>

		<table border="0" width="400" cellpadding="5" cellspacing="5">
			<tr>
				<td><label for="masterVolume" class="nodisable">Master
					Volume</label></td>
				<td>
					<div class="masterVolumeSlider" id="masterVolume"></div>
				</td>
				<td><label for="masterVolume" id="masterVolumeValue">100</label>
				</td>
			</tr>
			<tr>
				<td><label for="loop">Loop</label></td>
				<td>
					<div class="loopSlider" id="loop"></div>
				</td>
				<td><label for="loop" id="loopValue">0</label></td>
			</tr>
			<tr>
				<td><label for="delay">Delay</label></td>
				<td>
					<div class="delaySlider" id="delay"></div>
				</td>
				<td><label for="delay" id="delayValue">0 seconds</label></td>
			</tr>
			<tr>
				<td><label for="offset">Offset</label></td>
				<td>
					<div class="offsetSlider" id="offset"></div>
				</td>
				<td><label for="offset" id="offsetValue">null seconds</label>
				</td>
			</tr>
		</table>

		<table border="0" width="400" cellpadding="5" cellspacing="5">
			<label>Audio Sprite Properties</label>
			<tr>
				<td><label for="startTime">StartTime</label></td>
				<td>
					<div class="startTimeSlider" id="startTime"></div>
				</td>
				<td><label for="startTime" id="startTimeValue">0 seconds</label>
				</td>
			</tr>
			<tr>
				<td><label for="duration">Duration</label></td>
				<td>
					<div class="durationSlider" id="duration"></div>
				</td>
				<td><label for="duration" id="durationValue">0 seconds</label>
				</td>
			</tr>
		</table>
	</form>

	<form id="instanceControls">
		<p>Select a playing sound to stop, set volume, set pan, or set position.
			<br/>Use Clear to remove an instance from this list.</p>
		<select id="nowPlaying" multiple="multiple" disabled="disabled"
				class="select">
			<option value="-1">-- No Audio Playing --</option>
		</select>
		<input id="playBtn" name="play" type="button" value="Play"/>
		<input id="pauseBtn" name="pause" type="button" value="Pause"/>
		<input id="stopBtn" name="stop" type="button" value="Stop"/>
		<input id="muteBtn" name="mute" type="button" value="Mute"/>
		<input id="clearBtn" name="clear" type="button" value="Clear"/>
		<input id="clearAllBtn" name="clearAll" type="button"
			   value="Clear All"/>

		<br/>
		<br/>
		<table border="0" width="400" cellpadding="5" cellspacing="5">
			<!-- OJR it would be nice if this lined up with the library table.  Note adding <br/> does not line it up -->
			<tr>
				<td><label for="volume">Instance Volume</label></td>
				<td>
					<div id="volume" class="volumeSlider"></div>
				</td>
				<td><label for="volume" id="volumeValue">100</label></td>
			</tr>
			<tr>
				<td><label for="instanceLoop">Loop</label></td>
				<td>
					<div class="instanceLoopSlider" id="instanceLoop"></div>
				</td>
				<td><label for="instanceLoop" id="instanceLoopValue">0</label>
				</td>
			</tr>
			<tr>
				<td><label for="pan">Pan</label></td>
				<td>
					<div class="panSlider" id="pan"></div>
				</td>
				<td><label for="pan" id="panValue">0</label></td>
			</tr>
			<tr>
				<td><label for="pos">Position</label></td>
				<td>
					<div class="posSlider" id="pos"></div>
				</td>
				<td><label for="pos" id="posValue">0</label></td>
			</tr>
		</table>
		<table border="0" width="400" cellpadding="5" cellspacing="5">
			<label>Instance Audio Sprite Properties</label>
			<tr>
				<td><label for="instanceStartTime">StartTime</label></td>
				<td>
					<div class="instanceStartTimeSlider" id="instanceStartTime"></div>
				</td>
				<td><label for="instanceStartTime" id="instanceStartTimeValue">0 seconds</label>
				</td>
			</tr>
			<tr>
				<td><label for="instanceDuration">Duration</label></td>
				<td>
					<div class="instanceDurationSlider" id="instanceDuration"></div>
				</td>
				<td><label for="instanceDuration" id="instanceDurationValue">0 seconds</label>
				</td>
			</tr>
		</table>
	</form>

</div>

<div id="error">
	<h2>Sorry!</h2>

	<p>SoundJS is not currently supported in your browser.</p>

	<p>Please <a href="http://github.com/CreateJS/SoundJS/issues" target="_blank">log a bug</a>
		with the device and browser you are using. Thank you.</p>
</div>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.9.2/jquery-ui.min.js"></script>

<script type="text/javascript" src="../lib/soundjs-NEXT.js"></script>
<!-- Note: FlashAudioPlugin is only needed to support older browsers -->
<script type="text/javascript" src="../lib/flashaudioplugin-NEXT.js"></script>

<!-- We also provide hosted minified versions of all CreateJS libraries.
	http://code.createjs.com -->

<script id="editable">
	// Read the URL Params. We need to do this to determine the plugin mode.
	var params = {};
	var pieces = window.location.search.slice(1).split("&");
	for (var i = 0, l = pieces.length; i < l; i++) {
		var parts = pieces[i].split("=");
		params[parts[0]] = parts[1];
	}

	var instanceHash = {};  //store instances as they are created

	var audioInterval = null;
	var intervalTime = 100;

	function init() {
		createjs.FlashAudioPlugin.swfPath = "../src/soundjs/flashaudio/" // Initialize the base path from this document to the Flash Plugin
		if (params.type == "flash") {
			createjs.Sound.registerPlugins([createjs.FlashAudioPlugin]);
		} else if (params.type == "html5") {
			createjs.Sound.registerPlugins([createjs.HTMLAudioPlugin]);
		} else {
			createjs.Sound.registerPlugins([createjs.WebAudioPlugin, createjs.HTMLAudioPlugin, createjs.FlashAudioPlugin]);
		}

		if (!createjs.Sound.isReady()) {
			document.getElementById("error").style.display = "block";
			document.getElementById("content").style.display = "none";
			return;
		}

		var pluginStatus = document.getElementById("activePlugin");
		pluginStatus.innerHTML = "Active Plugin is " + createjs.Sound.activePlugin.toString();  // innerText does not work in FF

		// Library controls
		// note -1 will be considered null
		$(".offsetSlider").slider({value: -1,
									  min: -1,
									  max: 10,
									  disabled: false,
									  change: handleSliderChange
								  });
		$(".offsetSlider").data("units", "second");

		$(".delaySlider").slider({value: 0,
									 min: 0,
									 max: 10,
									 disabled: false,
									 change: handleSliderChange
								 });
		$(".delaySlider").data("units", "second");

		$(".startTimeSlider").slider({value: 0,
										 min: 0,
										 max: 10,
										 disabled: false,
										 change: handleSliderChange
									 });
		$(".startTimeSlider").data("units", "second");

		$(".durationSlider").slider({value: 0,
										min: 0,
										max: 10,
										disabled: false,
										change: handleSliderChange
									});
		$(".durationSlider").data("units", "second");

		$(".masterVolumeSlider").slider({value: 100,
											min: 0,
											max: 100,
											disabled: false,
											change: handleSliderChange
										});

		$(".loopSlider").slider({value: 0,
									min: -1,
									max: 5,
									disabled: false,
									change: handleSliderChange
								});

		$("#library").change(selectItem);
		$("#playSoundBtn").click(playSound);
		$("#createSoundBtn").click(createSound);
		$("#stopAllSoundsBtn").click(function (event) {
			//clearInterval(audioInterval);
			createjs.Sound.stop();
		});
		$("#muteAllSoundsBtn").click(function (event) {
			var muted = !createjs.Sound.muted;
			createjs.Sound.muted = muted;
			$("#muteAllSoundsBtn").attr("value", muted ? "Unmute All Sounds" : "Mute All Sounds");
		});

		$(".masterVolumeSlider").on('slidestop', function (event) {
			var value = $(this).slider("option", "value");
			createjs.Sound.volume = value / 100;
		});

		// instance controls
		$(".panSlider").slider({value: 0,
								   min: -1,
								   max: 1,
								   step: 0.1,  // gives us a nicer range for pan
								   disabled: true,
								   change: handleSliderChange
							   });

		$(".volumeSlider").slider({value: 100,
									  min: 0,
									  max: 100,
									  disabled: true,
									  change: handleSliderChange
								  });

		$(".instanceLoopSlider").slider({value: 0,
											min: -1,
											max: 5,
											disabled: true,
											change: handleSliderChange
										});

		$(".posSlider").slider({value: 0,
								   min: 0,
								   max: 100,
								   disabled: true,
								   change: handleSliderChange
							   });

		$(".instanceStartTimeSlider").slider({value: 0,
										 min: 0,
										 max: 10,
										 disabled: true,
										 change: handleSliderChange
									 });
		$(".instanceStartTimeSlider").data("units", "second");

		$(".instanceDurationSlider").slider({value: 0,
										min: 0,
										max: 10,
										disabled: true,
										change: handleSliderChange
									});
		$(".instanceDurationSlider").data("units", "second");

		$("#nowPlaying").change(selectInstance);
		$("#playBtn").click(function (event) {
			var instance = getInstance();
			if (instance == null) {
				return;
			}

			var playProps = {};
			var interrupt = $("#interrupt").get(0);
			playProps.interrupt = interrupt.options[interrupt.selectedIndex].value;
			playProps.loop = $(".instanceLoopSlider").slider("option", "value");
			playProps.delay = $(".delaySlider").slider("option", "value") * 1000;
			playProps.offset = $(".offsetSlider").slider("option", "value") * 1000;
			if (playProps.offset < 0) {
				playProps.offset = null;
			}
			playProps.volume = $(".volumeSlider").slider("option", "value") / 100;
			playProps.pan = $(".panSlider").slider("option", "value");
			instance.play(playProps);
		});
		$("#stopBtn").click(function (event) {
			var instance = getInstance();
			if (instance == null) {
				return;
			}
			instance.stop();
		});
		$("#pauseBtn").click(function (event) {
			var instance = getInstance();
			if (instance == null) {
				return;
			}
			instance.paused ? instance.paused = false : instance.paused = true;
			$("#pauseBtn").attr("value", instance.paused ? "Resume" : "Pause");
		});
		$("#muteBtn").click(function (event) {
			var instance = getInstance();
			if (instance == null) {
				return;
			}
			instance.muted = !instance.muted;
			$("#muteBtn").attr("value", instance.muted ? "Unmute" : "Mute");
		});
		$("#clearBtn").click(function (event) {
			var instance = getInstance();
			if (instance == null) {
				return;
			}
			instance.stop();
			removeSound(instance);
		});
		$("#clearAllBtn").click(function (event) {
			clearInterval(audioInterval);
			createjs.Sound.stop();
			removeSound("all");
		});

		$(".volumeSlider").on('slidestop', function (event) {
			var instance = getInstance();
			if (instance == null) {
				return;
			}
			var value = $(this).slider("option", "value");
			instance.volume = value / 100;
		});

		$(".instanceLoopSlider").on('slidestop', function (event) {
			var instance = getInstance();
			if (instance == null) {
				return;
			}
			var value = $(this).slider("option", "value");
			instance.loop = value;
		});

		$(".panSlider").on('slidestop', function (event) {
			var instance = getInstance();
			var value = $(this).slider("option", "value");
			instance.pan = value;
		});

		$(".posSlider").on('slidestop', function (event) {
			var instance = getInstance();
			var value = $(this).slider("option", "value");
			instance.position = (value / 100 * instance.duration);
			audioInterval = setInterval(setPosSlider, intervalTime);
		});
		$(".posSlider").on('slidestart', function (event) {
			clearInterval(audioInterval);
		});

		$(".instanceStartTimeSlider").on('slidestop', function (event) {
			var instance = getInstance();
			if (instance == null) {return;}
			var value = $(this).slider("option", "value");
			instance.startTime = value * 1000;
		});

		$(".instanceDurationSlider").on('slidestop', function (event) {
			var instance = getInstance();
			if (instance == null) {return;}
			var value = $(this).slider("option", "value");
			instance.duration = value * 1000;
		});

		enableSet("sound", false);
		enableSet("instance", false);

		var assetsPath = "../_assets/audio/";
		var sounds = [
			{id: "Music", src: "M-GameBG.ogg", data: 2},
			{id: "Humm (mp3)", src: "Humm.mp3", defaultPlayProps:{interrupt:createjs.Sound.INTERRUPT_ANY, loop:-1, volume:0.5, offset: 2000}},
			{id: "Humm", src: "Humm.ogg"},
			{id: "Thunder", src: "Thunder1.ogg", data: 3},
			{id: "Rat Damage", src: "R-Damage.ogg", type: "sound"},
			{id: "Cabin Boy", src: "U-CabinBoy3.ogg", type: "sound", data: 1},
			{src: "Game-AudioSprite.ogg", data: {
				audioSprite: [
					{id: "Audio Sprite Break", startTime: 0, duration: 500},
					{id: "Audio Sprite Shot", startTime: 1000, duration: 245, defaultPlayProps:{loop:-1, volume:0.75}},
					{id: "Audio Sprite Death", startTime: 1700, duration: 1074}
				]}
			}
		];

		createjs.Sound.alternateExtensions = ["mp3"];	// add other extensions to try loading if the src file extension is not supported
		createjs.Sound.addEventListener("fileload", createjs.proxy(addSoundToList, this)); // add an event listener for when load is completed
		createjs.Sound.registerSounds(sounds, assetsPath);
	}

	function addSoundToList(event) {
		var list = $("#library").get(0);
		if (event.data.audioSprite) {
			for (var i = event.data.audioSprite.length; i--;) {
				list.options.add(new Option((event.data.audioSprite[i].id) + " (" + (event.data.channels || "unknown") + ")", event.data.audioSprite[i].id));  //event.data should never be undefined, because it is set to the max limit by SoundJS
			}
		} else {
			list.options.add(new Option((event.id || event.src) + " (" + (event.data || "unknown") + ")", event.id));  //event.data should never be undefined, because it is set to the max limit by SoundJS
		}
	}

	function handleSliderChange(evt) {
		var units = $("." + this.id + "Slider").data("units");
		var value = $(this).slider("option", "value");
		if (this.id == "offset" && value == -1) {
			value = null;
		}
		$("#" + this.id + "Value").text(value + (units ? " " + units + (value == 1 ? "" : "s") : ""));
	}

	function playSound(event) {
		var list = $("#library").get(0);
		if (list.selectedIndex == -1) {
			return;
		}

		// Options
		var playProps = {};
		var interrupt = $("#interrupt").get(0);
		playProps.interrupt = interrupt.options[interrupt.selectedIndex].value;
		playProps.loop = $(".loopSlider").slider("option", "value");
		playProps.delay = $(".delaySlider").slider("option", "value") * 1000;
		playProps.offset = $(".offsetSlider").slider("option", "value") * 1000;
		if (playProps.offset < 0) {
			playProps.offset = null;
		}
		playProps.startTime = $(".startTimeSlider").slider("option", "value") * 1000;
		playProps.duration = $(".durationSlider").slider("option", "value") * 1000;
		if (playProps.duration == 0) {
			playProps.startTime = null;
			playProps.duration = null;
		}

		for (var i = 0, l = list.options.length; i < l; i++) {
			if (!list.options[i].selected) {
				continue;
			}
			var item = list.options[i];

			var instance = createjs.Sound.createInstance(item.value, playProps.startTime, playProps.duration);
			instance.handleSuccessProxy = createjs.proxy(handlePlaySuccess, instance);	// OJR kind of hacky
			instance.addEventListener("succeeded", instance.handleSuccessProxy);
			//instance.addEventListener("interrupted", createjs.proxy(handlePlayFailed,instance));
			//instance.addEventListener("failed", createjs.proxy(handlePlayFailed,instance));
			//instance.addEventListener("complete", createjs.proxy(handleSoundComplete,instance));

			instance.play(playProps);
		}
	}

	function createSound(event) {
		var list = $("#library").get(0);
		if (list.selectedIndex == -1) {
			return;
		}

		var startTime = $(".startTimeSlider").slider("option", "value") * 1000;
		var duration = $(".durationSlider").slider("option", "value") * 1000;
		if (duration == 0) {
			startTime = null;
			duration = null;
		}

		for (var i = 0, l = list.options.length; i < l; i++) {
			if (!list.options[i].selected) {
				continue;
			}
			var item = list.options[i];
			var instance = createjs.Sound.createInstance(item.value, startTime, duration);
			instance.handleSuccessProxy = null;

			handlePlaySuccess({target:instance});
		}
	}

	// Create a sound, add listeners, and try playing it.
	function handlePlaySuccess(event) {
		instance = event.target;
		instanceHash[instance.uniqueId] = instance;
		instance.removeEventListener("succeeded", instance.handleSuccessProxy);  // because we only want this to fire the first time we start playing
		delete(instance.handleSuccessProxy);

		var nowPlaying = $("#nowPlaying").get(0);

		// Put in the nowPlaying list. (Remember to remove first temp item)
		if (nowPlaying.options[0].value == "-1") {
			nowPlaying.remove(0);
			nowPlaying.disabled = false;
		} else {
			for (var j = nowPlaying.options.length - 1; j >= 0; j--) {
				if (nowPlaying.options[j].value == instance.uniqueId) {
					if (nowPlaying.options.remove) {
						nowPlaying.options.remove(j);
					} else if (nowPlaying.remove) {
						nowPlaying.remove(j);
					}
				}
			}
		}

		nowPlaying.options.add(new Option(instance.src + "(" + instance.uniqueId + ")", instance.uniqueId));
	}

	// Playback failed (usually interrupt failed)
	function handlePlayFailed(event) {
		removeSound(event.target);
	}

	// Remove the sound from the list.
	function removeSound(instance) {
		var currentInstance = getInstance();
		if (currentInstance && currentInstance.uniqueId == instance.uniqueId) {
			clearInterval(audioInterval);
		}
		delete(instanceHash[instance.uniqueId]);
		var list = $("#nowPlaying").get(0);
		for (var i = list.options.length - 1; i >= 0; i--) {
			if (instance == "all" || list.options[i].value == instance.uniqueId) {
				if (list.selectedIndex == i) {
					enableSet("instance", false);
				}
				if (list.options.remove) {
					list.options.remove(i);
				}
				else if (list.remove) {
					list.remove(i);
				}
				if (instance != "all") {
					break;
				}
			}
		}
		if (list.options.length == 0) {
			list.options.add(new Option("-- No Audio Playing --", -1));
			list.disabled = true;
			enableSet("instance", false);
		} else if (list.selectedIndex > -1) {
			var item = list.options[list.selectedIndex];
		}

	}

	// Get the currently selected sound from nowPlaying
	function getInstance() {
		var list = $("#nowPlaying").get(0);
		if (list.selectedIndex == -1) {
			return null;
		}

		var item = list.options[list.selectedIndex];
		if (item == null) {
			return null;
		}

		var instance = instanceHash[item.value];
		return instance;
	}

	// A library item was selected
	function selectItem(event) {
		var list = $("#library").get(0);
		if (list.selectedIndex != -1) {
			enableSet("sound", true)
		} else {
			enableSet("sound", false)
		}
	}

	// A playing instance was selected
	function selectInstance(event) {
		clearInterval(audioInterval);
		var list = $("#nowPlaying").get(0);
		if (list.selectedIndex > -1) {
			enableSet("instance", true);
			var instance = getInstance();

			var value = instance.volume * 100 | 0;
			$(".volumeSlider").slider("value", value);
			$("#volumeValue").text(value);

			value = instance.loop;
			$(".instanceLoopSlider").slider("value", value);
			$("#instaceLoopValue").text(value);

			value = instance.pan | 0;
			$(".panSlider").slider("value", value);
			$("#panValue").text(value);

			setPosSlider();
			audioInterval = setInterval(setPosSlider, intervalTime);

			value = instance.startTime / 1000 | 0;
			$(".instanceStartTimeSlider").slider("value", value);
			$("#instaceStartTimeValue").text(value);

			value = instance.duration / 1000 | 0;
			$(".instanceDurationSlider").slider("value", value);
			$("#instaceDurationpValue").text(value);

			$("#pauseBtn").attr("value", instance.paused ? "Resume" : "Pause");
			$("#muteBtn").attr("value", instance.muted ? "Unmute" : "Mute");
		} else {
			enableSet("instance", false);
		}
	}

	function setPosSlider() {
		var instance = getInstance();
		var value = instance.position / instance.duration * 100 | 0;
		$(".posSlider").slider("value", value);
		$("#posValue").text(instance.position / instance.duration * 100 | 0);
	}

	// Toggle the enabled property of a named set of components in a specific form
	function enableSet(name, enabled) {
		switch (name) {
			case "sound":
				enableItems("playControls", enabled, ["playSoundBtn", "createSoundBtn", "interrupt", "loop", "delay", "offset", "startTime", "duration"]);
				break;
			case "instance":
				enableItems("instanceControls", enabled, ["play", "pause", "stop", "clear", "volume", "instanceLoop", "pan", "pos", "mute", "instanceStartTime", "instanceDuration"]);
				break;
		}
	}

	// Toggle the enabled property of a number of named elements in a form
	function enableItems(formName, value, items) {
		var form = $("#" + formName);
		var element = form.get(0);
		if (element == null) {
			return;
		}
		value ? form.removeClass("disabled") : form.addClass("disabled");
		for (var i = 0, l = items.length; i < l; i++) {
			var item = element[items[i]];

			if ($('.' + items[i] + 'Slider')) {
				$('.' + items[i] + 'Slider').slider('option', 'disabled', !value);
			}

			if (item == null) {
				continue;
			}
			item.disabled = !value;
		}
	}
</script>

</body>
</html>
